package com.lijin.batchsys.framework.control;

import java.util.Date;
import java.util.concurrent.atomic.AtomicBoolean;

import org.apache.log4j.Logger;

import com.lijin.batchsys.framework.common.AssertUtil;
import com.lijin.batchsys.framework.common.BatchSysException;
import com.lijin.batchsys.framework.common.BatchUtil;

public abstract class BatchSysTask implements IBatchSysTask {
	
	private static final Logger logger = Logger.getLogger(BatchSysTask.class);
	
	protected String bhDate;   //批量日期
	protected String nextBhDate;   //批量下一日
	protected String preBhDate;  //批量上一日
	
	private AtomicBoolean runningFlg = new AtomicBoolean(false);
	
	/**
	 * 执行业务操作的模板方法
	 * @param batchDate 必须传入
	 * @throws Exception
	 */
	@Override
	public void execute(Date batchDate) {
		
		AssertUtil.objIsNull(batchDate, "传入的日期不能为");
		
		// 同时只允许一个进程进入方法体
		if (runningFlg.compareAndSet(false, true)) {
			try {
				initDate(batchDate);
				// 为业务逻辑处理方法进行预处理工作
				preProcess();
				// 业务逻辑处理
				doProcess();
			} catch (Throwable e) {
				logger.error(e);
				throw new BatchSysException(e);
			} finally {
				runningFlg.set(false);
				// 为业务逻辑处理方法进行处理后工作
				postProcess();
			}
		} else {
			throw new BatchSysException("已经有一个线程在执行当前任务");
		}
	}

	/**
	 * 由各个子任务类实现各自的业务方法
	 * @throws Exception
	 */
	protected abstract void doProcess() throws Exception;

	/**
	 * 可由子任务类来实现该方法
	 */
	protected void preProcess() { }
	
	/**
	 * 可由子任务类来实现该方法
	 */
	protected void postProcess() { }

	/**
	 * 根据传入的日期初始化业务类需要用到的各个日期
	 * @param batchDateStr
	 */
	private void initDate(Date batchDate) {
		bhDate = BatchUtil.formatDateTo8Str(batchDate);
		nextBhDate = BatchUtil.nextDay(batchDate);
		preBhDate = BatchUtil.preDay(batchDate);
	}
	
	public boolean isRunning() {
		return runningFlg.get();
	}
}
